// System includes
#include <QFont>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QStyleOptionGraphicsItem>
#include <QPainter>
#include <math.h>

// Local includes
#include "yigsynthgraphic.h"
#include "graphics/yigcolorkit.h"

extern QString USER_NAME;
extern bool ONLINE;
#define  PI 3.141592654


////////////////////
// YigSynthGraphic
///////////////////

QPixmap* YigSynthGraphic::circleImage;

const double YigSynthGraphic::SQRT_THREE = 1.73205081;

const double YigSynthGraphic::AUDIO_INPUT_X = ELLIPSE_SIZE/2;
const double YigSynthGraphic::AUDIO_INPUT_Y = ELLIPSE_SIZE/2;

const double YigSynthGraphic::AUDIO_OUTPUT_X = ELLIPSE_SIZE/2;
const double YigSynthGraphic::AUDIO_OUTPUT_Y = ELLIPSE_SIZE/2;

const double YigSynthGraphic::MOD_INPUT_X = ELLIPSE_SIZE/2;
const double YigSynthGraphic::MOD_INPUT_Y = ELLIPSE_SIZE/2;

const int YigSynthGraphic::MOD_FIELD_SIZE = ELLIPSE_SIZE * 3;
const int YigSynthGraphic::MOD_FIELD_2_SIZE = ELLIPSE_SIZE * 2;

bool YigSynthGraphic::staticImageInitBool = false;
void YigSynthGraphic::initCircleImage()
{
    staticImageInitBool = true;
    circleImage = new QPixmap(":/images/graphics/SnakeCircle.png");
}

YigSynthGraphic::YigSynthGraphic(QString synthType, QString mapKey, const QPointF &point, float param1, float param2,
                                 int outBus, QGraphicsScene *scene) :
    mMapKey(mapKey),
    audioOutBus(outBus),
    selectingUser(" "),
    QGraphicsEllipseItem(0, 0, ELLIPSE_SIZE, ELLIPSE_SIZE, 0, scene)
{
    mSynthType = synthType;
    autoCableCounter = 0;
    moveBy(point.x(), point.y());
    setFlag( QGraphicsItem::ItemIsSelectable, true );
    setFlag( QGraphicsItem::ItemIsMovable, true );
    setFlag(QGraphicsItem::ItemSendsGeometryChanges);
    setZValue(10);
    //setCacheMode(QGraphicsItem::DeviceCoordinateCache);

    //setAcceptsHoverEvents(true);

    // MOD FIELD 1
    modField1 = new YigModField(this, param1, 0, 0, MOD_FIELD_SIZE, MOD_FIELD_SIZE, this);
    modField1->moveBy((-MOD_FIELD_SIZE/2) + (ELLIPSE_SIZE/2), (-MOD_FIELD_SIZE/2) + (ELLIPSE_SIZE/2));
    modField1->setFlag( QGraphicsItem::ItemIsSelectable, true );
    modField1->setFlag( QGraphicsItem::ItemIsMovable, false );

    QColor outlineColor = YigColorKit::background2;
    pen.setColor(QColor(0, 0, 0, 25));
    pen.setColor( outlineColor );
    modField1->setPen( pen );

    //modField1->setCacheMode(QGraphicsItem::DeviceCoordinateCache);

    /*
    QRadialGradient gradient(QPointF(MOD_FIELD_SIZE/2, MOD_FIELD_SIZE/2), MOD_FIELD_SIZE/2,
                             QPointF(MOD_FIELD_SIZE/2, MOD_FIELD_SIZE/2));

    gradient.setColorAt(0, QColor(0, 0, 0, 0));
    gradient.setColorAt(0.3, QColor(0, 0, 0, 100));
    gradient.setColorAt(0.75, QColor(0, 0, 0, 170));
    gradient.setColorAt(1, QColor(0, 0, 0, 50));
    QBrush radialBrush(gradient);*/
    //modField1->setBrush( QColor(0, 0, 0, 160) );
    modField1->setBrush(Qt::NoBrush);

    QColor modColor = YigColorKit::background2;
    modColor.setAlpha(150);
    //brush.setColor(modColor);
    //modField1->setBrush(QBrush(modColor));

    modField1->setFlag(QGraphicsItem::ItemStacksBehindParent, true);
    modField1->setZValue(0);
    //modField1->setCacheMode( QGraphicsItem::DeviceCoordinateCache );

    // MOD FIELD 2
    modField2 = new YigModField2(this, param2, 0, 0, MOD_FIELD_2_SIZE, MOD_FIELD_2_SIZE, this);
    modField2->moveBy(((-MOD_FIELD_2_SIZE/2) + (ELLIPSE_SIZE/2)), ((-MOD_FIELD_2_SIZE/2) + (ELLIPSE_SIZE/2)));
    modField2->setFlag( QGraphicsItem::ItemIsSelectable, true );
    modField2->setFlag( QGraphicsItem::ItemIsMovable, false );
    //modField2->setPen( pen );
    modField2->setPen(Qt::NoPen);

    /*
    QRadialGradient gradient2(QPointF(MOD_FIELD_2_SIZE/2, MOD_FIELD_2_SIZE/2), MOD_FIELD_2_SIZE/2,
                              QPointF(MOD_FIELD_2_SIZE/2, MOD_FIELD_2_SIZE/2));
    gradient2.setColorAt(0, QColor(255, 255, 255, 0));
    gradient2.setColorAt(0.5, QColor(0, 0, 0, 0));
    gradient2.setColorAt(0.7, QColor(255, 255, 255, 160));
    gradient2.setColorAt(0.8, QColor(255, 255, 255, 160));
    gradient2.setColorAt(0.95, QColor(255, 255, 255, 100));
    gradient2.setColorAt(1, QColor(0, 0, 0, 100));
    QBrush radialBrush2(gradient2);
    modField2->setBrush( radialBrush2 );*/
    modField2->setBrush(Qt::NoBrush);

    //modColor = YigColorKit::focus1Highlight;
    //modColor.setAlpha(100);
    //modField2->setBrush(modColor);

    //modField2->setCacheMode(QGraphicsItem::DeviceCoordinateCache);;
    modField2->setFlag(QGraphicsItem::ItemStacksBehindParent);
    //modField2->setZValue(3);
    //modField2->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
    // AUDIO OUTPUT
    /*
    audioOutput = new YigEllipseItem( this, 0, 0, SMALL_ELLIPSE_SIZE, SMALL_ELLIPSE_SIZE, this );
    //audioOutput->moveBy((ELLIPSE_SIZE/2) - (SMALL_ELLIPSE_SIZE/2), ELLIPSE_SIZE - SMALL_ELLIPSE_SIZE);
    audioOutput->moveBy(7.5 + TRI_OFFSET_X, 7.5*SQRT_THREE + TRI_OFFSET_Y);

    audioOutput->setFlag( QGraphicsItem::ItemIsSelectable, false );
    audioOutput->setFlag( QGraphicsItem::ItemIsMovable, false );
    audioOutput->setCacheMode(QGraphicsItem::DeviceCoordinateCache);*/

    // AUDIO INPUT
    /*
    audioInput = new YigEllipseItem( this, 0, 0, SMALL_ELLIPSE_SIZE, SMALL_ELLIPSE_SIZE, this );
    //audioInput->moveBy((ELLIPSE_SIZE/2) - (SMALL_ELLIPSE_SIZE/2), 0);
    audioInput->moveBy(0 + TRI_OFFSET_X, 0 + TRI_OFFSET_Y);*/

    audioInput = new QGraphicsEllipseItem(0, 0, AUDIO_ELLIPSE_SIZE, AUDIO_ELLIPSE_SIZE, this);
    audioInput->moveBy((ELLIPSE_SIZE/2) - (AUDIO_ELLIPSE_SIZE/2), (ELLIPSE_SIZE/2) - (AUDIO_ELLIPSE_SIZE/2));
    audioInput->setFlag( QGraphicsItem::ItemIsSelectable, false );
    audioInput->setFlag( QGraphicsItem::ItemIsMovable, false );
    //audioInput->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    audioInput->setZValue(20);

    // MOD INPUT
    /*
    modInput = new YigEllipseItem( this, 0, 0, SMALL_ELLIPSE_SIZE, SMALL_ELLIPSE_SIZE, this );
    //modInput->moveBy(0, (ELLIPSE_SIZE/2) - (SMALL_ELLIPSE_SIZE/2));
    modInput->moveBy(15 + TRI_OFFSET_X, 0 + TRI_OFFSET_Y);*/

    modInput = new QGraphicsEllipseItem(0, 0, MOD_ELLIPSE_SIZE, MOD_ELLIPSE_SIZE, this);
    modInput->moveBy((ELLIPSE_SIZE/2) - (MOD_ELLIPSE_SIZE/2), (ELLIPSE_SIZE/2) - (MOD_ELLIPSE_SIZE/2));
    modInput->setFlag( QGraphicsItem::ItemIsSelectable, false );
    modInput->setFlag( QGraphicsItem::ItemIsMovable, false );
    //modInput->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    modInput->setZValue(20);

    // Synth Label
    synthLabel = new QGraphicsSimpleTextItem(this);
    synthLabel->moveBy( ELLIPSE_SIZE + 5, ELLIPSE_SIZE/2 - 4);
    synthLabel->setText(synthType);
    //QFont labelFont("Helvetica [Cronyx]", 11);
    QFont labelFont("monaco", 10);
    synthLabel->setFont(labelFont);
    synthLabel->setFlag( QGraphicsItem::ItemIsSelectable, false );
    synthLabel->setFlag( QGraphicsItem::ItemIsMovable, false );
    //synthLabel->setPen(YigColorKit::accent);
    //synthLabel->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    synthLabel->setCacheMode(QGraphicsItem::DeviceCoordinateCache);

    outlineColor = QColor( 0, 0, 0, 255 );
    pen.setColor( outlineColor );
    audioInput->setPen(Qt::NoPen);
    //audioOutput->setPen(pen);
    modInput->setPen(Qt::NoPen);

    /*
    QRadialGradient gradient3(QPointF(ELLIPSE_SIZE/2, ELLIPSE_SIZE/2), ELLIPSE_SIZE/2,
                             QPointF(ELLIPSE_SIZE/2, ELLIPSE_SIZE/2));
    gradient3.setColorAt(0, QColor(0, 0, 0, 255));
    gradient3.setColorAt(0.8, QColor(0, 0, 0, 255));
    gradient3.setColorAt(1, QColor(0, 0, 0, 0));*/


    //setCacheMode( QGraphicsItem::DeviceCoordinateCache );
    /*
    QRadialGradient gradient4(QPointF(AUDIO_ELLIPSE_SIZE/2, AUDIO_ELLIPSE_SIZE/2), AUDIO_ELLIPSE_SIZE/2,
                             QPointF(AUDIO_ELLIPSE_SIZE/2, AUDIO_ELLIPSE_SIZE/2));
    gradient4.setColorAt(0, QColor(0, 0, 0, 255));
    gradient4.setColorAt(0.9, QColor(33, 33, 33, 255));
    gradient4.setColorAt(1, QColor(0, 0, 0, 255));
    audioInput->setBrush( QBrush(gradient4) );*/
    audioInput->setBrush(Qt::NoBrush);
    audioInput->setPen(Qt::NoPen);

    /*
    QRadialGradient gradient5(QPointF(MOD_ELLIPSE_SIZE/2, MOD_ELLIPSE_SIZE/2), MOD_ELLIPSE_SIZE/2,
                             QPointF(MOD_ELLIPSE_SIZE/2, MOD_ELLIPSE_SIZE/2));
    gradient5.setColorAt(0, YigColorKit::accent);
    gradient5.setColorAt(0.85, YigColorKit::accent);
    gradient5.setColorAt(1, QColor(0, 0, 0));
    modInput->setBrush( gradient5 );
    modInput->setPen(Qt::NoPen);*/


    // Arrows
    audioInArrow = new YigSignalArrow(AUDIO_INPUT, this);
    //audioOutArrow = new YigSignalArrow(AUDIO_OUTPUT, this);
    modInArrow = new YigSignalArrow(MOD_INPUT, this);

    //audioInput->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
    //modInput->setCacheMode( QGraphicsItem::DeviceCoordinateCache );


    //setCacheMode( QGraphicsItem::DeviceCoordinateCache );


    audioInput->setFlag(QGraphicsItem::ItemHasNoContents);
    modInput->setFlag(QGraphicsItem::ItemHasNoContents);
    //setFlag(QGraphicsItem::ItemHasNoContents);
    modField1->setFlag(QGraphicsItem::ItemHasNoContents);
    modField2->setFlag(QGraphicsItem::ItemHasNoContents);
    /*
    audioInput->setZValue(25);
    QColor penColor = YigColorKit::background2;
    penColor.setAlpha(200);
    pen = QPen(penColor);
    pen.setWidth(2);*/
    //setBrush(gradient3);
    setBrush(Qt::NoBrush);
    setPen(Qt::NoPen);
}

YigSynthGraphic::~YigSynthGraphic()
{
    deleteCables();
    delete modField1;
    delete modField2;
    delete audioInput;
    //delete audioOutput;
    delete modInput;
    delete synthLabel;
    delete audioInArrow;
    //delete audioOutArrow;
    delete modInArrow;
}

QBrush YigSynthGraphic::getBrush()
{
    return brush;
}


void YigSynthGraphic::updatePos( const QPointF& point )
{
    // Shouldn't this just be overridden?
    this->setPos(point);
    //emit posChanged( mMapKey, point );
}


/*
void YigSynthGraphic::keyboardDelete()
{
    //qDebug() << " DELETE: " << mMapKey;
    //deleteCables();
    emit synthKeyboardDeleted(mMapKey);
}*/

QString YigSynthGraphic::getMapKey()
{
    return mMapKey;
}

void YigSynthGraphic::setSynthType(QString synthType)
{
    mSynthType = synthType;
}

QString YigSynthGraphic::getSynthType()
{
    return mSynthType;
}

int YigSynthGraphic::getAudioOutBus()
{
    return audioOutBus;
}

void YigSynthGraphic::setAudioOutBus(int bus)
{
    audioOutBus = bus;
}

/*
void YigSynthGraphic::itemClick(QGraphicsItem *item)
{
    QPointF point;

    if(item == audioInput)
    {
        point.setX(pos().x() + AUDIO_INPUT_X);
        point.setY(pos().y() + AUDIO_INPUT_Y);
        emit ellipseClicked(mMapKey, AUDIO_INPUT, point);
    }

    else if(item == audioOutput)
    {
        point.setX(pos().x() + AUDIO_OUTPUT_X);
        point.setY(pos().y() + AUDIO_OUTPUT_Y);
        emit ellipseClicked(mMapKey, AUDIO_OUTPUT, point);
    }

    else if(item == modInput)
    {
        point.setX(pos().x() + MOD_INPUT_X);
        point.setY(pos().y() + MOD_INPUT_Y);
        emit ellipseClicked(mMapKey, MOD_INPUT, point);
    }

}
*/
void YigSynthGraphic::addAudioInputCable(YigCableGraphic *cable)
{
    audioInputCableList.append(cable);
}


void YigSynthGraphic::addAudioOutputCable(YigCableGraphic *cable)
{
    audioOutputCableList.append(cable);
    if(cable->getOutputType() == YigCableGraphic::AUDIO)
    {
        // Check for connecting synths NOT cable...hmmm...perhaps this should happen somewhere else...YigNetworkChannelView?
        if(audioInputCableList.contains(cable))
        {
            cable->setVisible(false);
            cable->setFlag(QGraphicsItem::ItemHasNoContents);
            //qDebug() << "INVISIBLE";
        }
    }

    else if(cable->getOutputType() == YigCableGraphic::MODULATION)
    {
        if(modInputCableList.contains(cable))
        {
            cable->setVisible(false);
            cable->setFlag(QGraphicsItem::ItemHasNoContents);
            //qDebug() << "INVISIBLE";
        }
    }
}


void YigSynthGraphic::addModInputCable(YigCableGraphic *cable)
{
    modInputCableList.append(cable);
}


bool YigSynthGraphic::removeAudioInputCable(QString cableMapKey)
{
    for(int i = 0; i < audioInputCableList.size(); i++)
    {
        if(audioInputCableList.at(i)->getMapKey() == cableMapKey)
        {
            audioInputCableList.removeAt(i);
            return true;
        }
    }

    return false;
}


bool YigSynthGraphic::removeAudioOutputCable(QString cableMapKey)
{
    for(int i = 0; i < audioOutputCableList.size(); i++)
    {
        if(audioOutputCableList.at(i)->getMapKey() == cableMapKey)
        {
            audioOutputCableList.removeAt(i);
            return true;
        }
    }

    return false;
}


bool YigSynthGraphic::removeModInputCable(QString cableMapKey)
{
    for(int i = 0; i < modInputCableList.size(); i++)
    {
        if(modInputCableList.at(i)->getMapKey() == cableMapKey)
        {
            modInputCableList.removeAt(i);
            return true;
        }
    }

    return false;
}

bool YigSynthGraphic::removeCable(QString cableMapKey)
{
    if(removeAudioInputCable(cableMapKey))
    {
        return true;
    }

    else if(removeAudioOutputCable(cableMapKey))
    {
        return true;
    }

    else if(removeModInputCable(cableMapKey))
    {
        return true;
    }

    else
    {
        return false;
    }
}

int YigSynthGraphic::type() const
{
    return YigBaseGraphic::SynthGraphicType;
}

void YigSynthGraphic::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QStyleOptionGraphicsItem myOption = (*option);
    myOption.state &= !QStyle::State_Selected;
    painter->drawPixmap(-MOD_FIELD_SIZE/3 - 1, -MOD_FIELD_SIZE/3 - 1, *circleImage);

    //painter->setClipRect(option->exposedRect);

    QGraphicsEllipseItem::paint(painter, &myOption, widget);

    /*
    // Paint our highlight here
    if(option->state & QStyle::State_Selected)
    {
        painter->setPen(YigBaseGraphic::highlightPen);
        painter->setBrush(Qt::NoBrush);
        painter->drawEllipse(boundingRect());
    }*/

    if(QString::compare(selectingUser, USER_NAME) == 0)
    {
        painter->setPen(YigBaseGraphic::localUserHighlight);
        painter->setBrush(Qt::NoBrush);
        painter->drawEllipse(boundingRect().center(), MOD_FIELD_SIZE/2, MOD_FIELD_SIZE/2);
        //painter->drawEllipse(boundingRect());
    }

    else if(QString::compare(selectingUser, " ") == 0)
    {

    }

    else
    {
        painter->setPen(YigBaseGraphic::otherUserHighlight);
        painter->setBrush(Qt::NoBrush);
        painter->drawEllipse(boundingRect().center(), MOD_FIELD_SIZE/2, MOD_FIELD_SIZE/2);
        //painter->drawEllipse(boundingRect());
    }
}

void YigSynthGraphic::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
{
    QGraphicsEllipseItem::mouseMoveEvent(event);

    if(ONLINE)
    {
        QList<QGraphicsItem*> items = scene()->selectedItems();
        for(int i = 0; i < items.size(); i++)
        {
            if(items.at(i)->type() == YigBaseGraphic::SynthGraphicType)
            {
                ((YigSynthGraphic*)items.at(i))->triggerUpdatePos();
            }
        }
    }
}

void YigSynthGraphic::triggerUpdatePos()
{
    emit posChanged(mMapKey, pos());
    emit posChanged(audioOutBus, scenePos());
}


QVariant YigSynthGraphic::itemChange(GraphicsItemChange change, const QVariant &value)
{
    //QVariant variant = QGraphicsEllipseItem::itemChange(change, value);
    //QVariant variant = QVariant(value);

    if(change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged)
    {
        // Preventing bug with synths ending up in the corner
        /*
        QPoint newPoint = value.toPoint();

        bool changed = false;
        if(newPoint.x() < 5)
        {
            //newPoint.setX(5);
            changed = true;
        }

        else if(newPoint.y() < 5)
        {
            //newPoint.setY(5);
            changed = true;
        }

        if(changed)
            return QVariant();*/

        updateCablePositions();


        if(autoCableCounter >= (19+(selectedSynthKeys.size()*3)))
        {
            autoCable();
            autoCableCounter = 0;
        }

        else
        {
            autoCableCounter++;
        }
        //QList<QGraphicsItem*> collidingItems = scene()->collidingItems(modField1);
    }

    else if(change == QGraphicsItem::ItemSelectedChange || change == QGraphicsItem::ItemSelectedHasChanged)
    {
        if(value.toBool())
        {
            selectingUser = USER_NAME;
            if(ONLINE)
            {
                emit selectedChanged(mMapKey, 1);
            }
        }

        else
        {
            selectingUser = " ";
            if(ONLINE)
            {
                emit selectedChanged(mMapKey, 0);
                modField1->update(modField1->boundingRect());
                modField2->update(modField2->boundingRect());
            }
        }
    }

    return QGraphicsEllipseItem::itemChange(change, value);
}


void YigSynthGraphic::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    pen.setWidth(3);
    //pen.setColor(YigColorKit::focus1);
    //pen.setStyle(Qt::DotLine);
    setPen(pen);
    setCursor(Qt::OpenHandCursor);
    QGraphicsItem::hoverEnterEvent(event);
}

void YigSynthGraphic::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{

    pen.setWidth(2);
    setPen( pen );
    setCursor(Qt::ArrowCursor);
    QGraphicsItem::hoverLeaveEvent(event);
}

void YigSynthGraphic::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    setCursor(Qt::ClosedHandCursor);
    QGraphicsEllipseItem::mousePressEvent(event);
}

void YigSynthGraphic::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    setCursor(Qt::OpenHandCursor);
    QGraphicsEllipseItem::mouseReleaseEvent(event);
}

void YigSynthGraphic::updateCablePositions()
{
    for(int i = 0; i < audioInputCableList.size(); i++)
    {
        audioInputCableList.at(i)->setPoint2(QPoint(pos().x() + AUDIO_INPUT_X, pos().y() + AUDIO_INPUT_Y));
    }

    for(int i = 0; i < audioOutputCableList.size(); i++)
    {
        audioOutputCableList.at(i)->setPoint1(QPoint(pos().x() + AUDIO_OUTPUT_X, pos().y() + AUDIO_OUTPUT_Y));
        /*
        //YigCableGraphic* cable = audioOutputCableList.at(i);
        if(audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::MODULATION)
        {
            audioOutputCableList.at(i)->setPoint1(QPoint(pos().x() + MOD_INPUT_X, pos().y() + MOD_INPUT_Y));
        }

        else
        {
            audioOutputCableList.at(i)->setPoint1(QPoint(pos().x() + AUDIO_OUTPUT_X, pos().y() + AUDIO_OUTPUT_Y));
        }*/
        //audioOutputCableList.at(i)->setPoint1(QPoint(pos().x() + AUDIO_OUTPUT_X, pos().y() + AUDIO_OUTPUT_Y));
    }

    for(int i = 0; i < modInputCableList.size(); i++)
    {
        modInputCableList.at(i)->setPoint2(QPoint(pos().x() + MOD_INPUT_X, pos().y() + MOD_INPUT_Y));
    }
}

// Iterate through the cable lists, calle keyboardDelete() on all of them and remove them from this list
void YigSynthGraphic::deleteCables()
{
    YigCableGraphic* cable;
    while(!audioInputCableList.isEmpty())
    {
        cable = audioInputCableList.takeFirst();
        if(cable && (cable != 0))
        {
            cable->keyboardDelete();
        }
    }

    audioInputCableList.clear();

    while(!audioOutputCableList.isEmpty())
    {
        cable = audioOutputCableList.takeFirst();
        if(cable && (cable != 0))
        {
            cable->keyboardDelete();
        }
    }

    audioOutputCableList.clear();

    while(!modInputCableList.isEmpty())
    {
        cable = modInputCableList.takeFirst();
        if(cable && (cable != 0))
        {
            cable->keyboardDelete();
        }
    }

    modInputCableList.clear();
}

void YigSynthGraphic::autoCable()
{

    QList<QGraphicsItem*> items = modField1->collidingItems();

    items.removeAll(audioInArrow);
    //items.removeAll(audioOutArrow);
    items.removeAll(modInArrow);

    QList<QString> addedSynths;
    bool cableFound = false;

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::SignalArrow)
        {
            YigSignalArrow* arrow = ((YigSignalArrow*) items.at(i));
            QString collisionSynth = arrow->getParentGraphic()->getMapKey();
            if(!selectedSynthKeys.contains(collisionSynth))
            {
                cableFound = false;
                EllipseType arrowType = arrow->getArrowType();

                switch(arrowType)
                {

                case AUDIO_INPUT:

                    for(int i = 0; i < audioOutputCableList.size(); i++)
                    {
                        if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth
                                && audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::AUDIO)
                        {
                            cableFound = true;
                            break;
                        }
                    }

                    if(!cableFound)
                    {
                        // Create Audio Output -> Audio Input cable
                        emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::AUDIO);
                        addedSynths.append(collisionSynth);
                    }

                    break;
                /*
                case AUDIO_OUTPUT:

                    for(int i = 0; i < audioInputCableList.size(); i++)
                    {
                        if(audioInputCableList.at(i)->getInputKey() == collisionSynth)
                        {
                            cableFound = true;
                            break;
                        }
                    }

                    if(!cableFound)
                    {
                        // Create Audio Input -> Output cable
                        emit autoCableTriggered(collisionSynth, mMapKey, YigCableGraphic::AUDIO);
                    }

                    break;*/

                case MOD_INPUT:

                    for(int i = 0; i < audioOutputCableList.size(); i++)
                    {
                        if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth
                                && audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::MODULATION)
                        {
                            cableFound = true;
                            break;
                        }
                    }

                    if(!cableFound)
                    {
                        // Create Audio Output -> Mod Input cable
                        emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::MODULATION);
                    }

                    break;

                }
            }


        }
    }



    items = audioInArrow->collidingItems();
    items.removeAll(modField1);
    cableFound = false;

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::ModFieldType)
        {
            QString collisionSynth = ((YigModField*) items.at(i))->getParentGraphic()->getMapKey();

            if(!selectedSynthKeys.contains(collisionSynth))
            {
                cableFound = false;

                for(int i = 0; i < audioInputCableList.size(); i++)
                {
                    if(audioInputCableList.at(i)->getInputKey() == collisionSynth)
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Audio Input -> Output cable
                    emit autoCableTriggered(collisionSynth, mMapKey, YigCableGraphic::AUDIO);
                    addedSynths.append(collisionSynth);
                }
            }
        }
    }

    items = modInArrow->collidingItems();
    items.removeAll(modField1);
    cableFound = false;

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::ModFieldType)
        {
            QString collisionSynth = ((YigModField*) items.at(i))->getParentGraphic()->getMapKey();

            if(!selectedSynthKeys.contains(collisionSynth))
            {
                cableFound = false;

                for(int i = 0; i < modInputCableList.size(); i++)
                {
                    if(modInputCableList.at(i)->getInputKey() == collisionSynth)
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Mod Input -> Output cable
                    emit autoCableTriggered(collisionSynth, mMapKey, YigCableGraphic::MODULATION);
                }
            }
        }
    }


    /*
    items = audioOutArrow->collidingItems();
    items.removeAll(modField1);
    cableFound = false;

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::ModFieldType)
        {
            QString collisionSynth = ((YigModField*) items.at(i))->getParentGraphic()->getMapKey();
            if(!selectedSynthKeys.contains(collisionSynth))
            {
                cableFound = false;

                for(int i = 0; i < audioOutputCableList.size(); i++)
                {
                    if((audioOutputCableList.at(i)->getOutputKey() == collisionSynth
                            && audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::AUDIO)
                            || addedSynths.contains(collisionSynth))
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Audio Output -> Audio Input cable
                    emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::AUDIO);
                }
            }
        }
    }*/


    /*
    items = audioOutArrow->collidingItems();
    items.removeAll(modField1);

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::ModFieldType)
        {
            QString collisionSynth = ((YigModField*) items.at(i))->getParentGraphic()->getMapKey();
            bool cableFound = false;

            for(int i = 0; i < audioOutputCableList.size(); i++)
            {
                if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth)
                {
                    cableFound = true;
                    break;
                }
            }

            if(!cableFound)
            {
                // Create Output -> Input cable
                emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::AUDIO);
            }
        }
    }*/

    /*
    QList<QGraphicsItem*> items = modField1->collidingItems();

    items.removeAll(audioInArrow);
    items.removeAll(audioOutArrow);
    items.removeAll(modInArrow);

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::SignalArrow)
        {
            YigSignalArrow* arrow = ((YigSignalArrow*) items.at(i));
            QString collisionSynth = arrow->getParentGraphic()->getMapKey();
            bool cableFound = false;
            EllipseType arrowType = arrow->getArrowType();

            switch(arrowType)
            {

            case AUDIO_INPUT:

                for(int i = 0; i < audioOutputCableList.size(); i++)
                {
                    if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth
                            && audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::AUDIO)
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Audio Output -> Audio Input cable
                    emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::AUDIO);
                }

                break;

            case AUDIO_OUTPUT:

                for(int i = 0; i < audioInputCableList.size(); i++)
                {
                    if(audioInputCableList.at(i)->getInputKey() == collisionSynth)
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Audio Input -> Output cable
                    emit autoCableTriggered(collisionSynth, mMapKey, YigCableGraphic::AUDIO);
                }

                break;

            case MOD_INPUT:

                for(int i = 0; i < audioOutputCableList.size(); i++)
                {
                    if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth
                            && audioOutputCableList.at(i)->getOutputType() == YigCableGraphic::MODULATION)
                    {
                        cableFound = true;
                        break;
                    }
                }

                if(!cableFound)
                {
                    // Create Audio Output -> Mod Input cable
                    emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::MODULATION);
                }

                break;

            }

        }
    }
    */
}

/*
OLD AUTO CABLE METHOD. Holding on to this in case I decide to revert back to the old method

void YigSynthGraphic::autoCable()
{
    QList<QGraphicsItem*> items = modField1->collidingItems();

    items.removeAll(modField1);

    for(int i = 0; i < items.size(); i++)
    {
        if(items.at(i)->type() == YigBaseGraphic::ModFieldType)
        {
            QString collisionSynth = ((YigModField*) items.at(i))->getParentGraphic()->getMapKey();
            bool cableFound = false;

            for(int i = 0; i < audioInputCableList.size(); i++)
            {
                if(audioInputCableList.at(i)->getInputKey() == collisionSynth)
                {
                    cableFound = true;
                    break;
                }
            }

            if(!cableFound)
            {
                // Create Input -> Output cable
                emit autoCableTriggered(collisionSynth, mMapKey, YigCableGraphic::AUDIO);
            }

            else
            {
                cableFound = false;
            }


            for(int i = 0; i < audioOutputCableList.size(); i++)
            {
                if(audioOutputCableList.at(i)->getOutputKey() == collisionSynth)
                {
                    cableFound = true;
                    break;
                }
            }

            if(!cableFound)
            {
                // Create Output -> Input cable
                emit autoCableTriggered(mMapKey, collisionSynth, YigCableGraphic::AUDIO);
            }

        }
    }
}
*/

void YigSynthGraphic::setParam1(float value)
{
    emit paramChanged(mMapKey, Param1, param1);
    param1 = value;
}

void YigSynthGraphic::setParam2(float value)
{
    emit paramChanged(mMapKey, Param2, param2);
    param2 = value;
}

void YigSynthGraphic::syncParam1(float value)
{
    //qDebug() << "SYNC PARAM1: " << value;
    if(!modField1->isSelected())
    {
        ((YigModField*) modField1)->syncParam1(value);
    }
}

void YigSynthGraphic::syncParam2(float value)
{
    //qDebug() << "SYNC PARAM2: " << value;
    if(!modField2->isSelected())
    {
        ((YigModField2*) modField2)->syncParam2(value);
    }
}

void YigSynthGraphic::setselectingUser(QString userName)
{
    selectingUser = userName;
    if(QString::compare(selectingUser, " ") == 0 || QString::compare(selectingUser, USER_NAME) == 0)
    {
        //qDebug() << "LOCAL USER?";
        setFlag(QGraphicsItem::ItemIsSelectable, true);
        setFlag(QGraphicsItem::ItemIsMovable, true);
        modField1->setFlag(QGraphicsItem::ItemIsSelectable, true);
        modField2->setFlag(QGraphicsItem::ItemIsSelectable, true);
    }

    else
    {
        //qDebug() << "Other USER?";
        setFlag(QGraphicsItem::ItemIsSelectable, false);
        setFlag(QGraphicsItem::ItemIsMovable, false);
        modField1->setFlag(QGraphicsItem::ItemIsSelectable, false);
        modField2->setFlag(QGraphicsItem::ItemIsSelectable, false);
    }
}

void YigSynthGraphic::broadcastParams()
{
    emit paramChanged(mMapKey, Param1, param1);
    emit paramChanged(mMapKey, Param2, param2);
}

////////////////////////
// YigEllipseItem
///////////////////////

YigEllipseItem::YigEllipseItem(YigSynthGraphic* synthGraphic, qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent) :
    QGraphicsEllipseItem( x, y, width, height, parent )
{
    parentGraphic = synthGraphic;
}

/*
int YigEllipseItem::type() const
{
    // Enable the use of qgraphicsitem_cast with this item
    return Type;
}
*/
void YigEllipseItem::setPos( const QPointF &pos )
{
    /*
    QPointF newPos = pos;
    if(newPos.x() < 5)
        newPos.setX(5);
    if(newPos.y() < 5)
        newPos.setY(5);

    if(newPos.x() > (scene()->width()-YigSynthGraphic::ELLIPSE_SIZE))
    {
        newPos.setX((scene()->width()-YigSynthGraphic::ELLIPSE_SIZE));
    }

    if(newPos.y() > (scene()->height()-YigSynthGraphic::ELLIPSE_SIZE))
    {
        newPos.setY((scene()->height()-YigSynthGraphic::ELLIPSE_SIZE));
    }*/

    QGraphicsEllipseItem::setPos( pos );
    parentGraphic->updatePos( pos );
    //qDebug() << "New Pos: " << newPos;
}

void YigEllipseItem::setPos( qreal x, qreal y )
{
    /*
    if(x < 5)
        x = 5;
    if(y < 5)
        y = 5;

    if(x > (scene()->width() - YigSynthGraphic::ELLIPSE_SIZE))
    {
        x = (scene()->width() - YigSynthGraphic::ELLIPSE_SIZE);
    }

    if(y > (scene()->height() - YigSynthGraphic::ELLIPSE_SIZE))
    {
        y = (scene()->height() - YigSynthGraphic::ELLIPSE_SIZE);
    }*/

    QGraphicsEllipseItem::setPos( x, y );
    parentGraphic->updatePos( this->pos() );
}

void YigEllipseItem::moveBy( qreal dx, qreal dy )
{
    QGraphicsEllipseItem::moveBy( dx, dy );
    parentGraphic->updatePos( this->pos() );
}

void YigEllipseItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsEllipseItem::mouseMoveEvent( event );
    parentGraphic->updatePos( this->pos() );
}

// event for local cable creation
/*
void YigEllipseItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsEllipseItem::mousePressEvent(event);
    parentGraphic->itemClick(this);
}
*/
/*
void YigEllipseItem::keyboardDelete()
{
    parentGraphic->keyboardDelete();
}*/


////////////////
// YigModField
///////////////

YigModField::YigModField(YigSynthGraphic *synthGraphic, float param, qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent) :
    QGraphicsEllipseItem( x, y, width, height, parent ),
    modArc(this),
    yigAttractor(this),
    modTriangle(this)
{
    //createModCircle();
    parentGraphic = synthGraphic;
    setTransformOriginPoint(boundingRect().width()/2, boundingRect().height()/2);
    rotationAngle = param * 360;
    setRotation(fmod(rotationAngle+180, 360));
    transformOriginPoint();
    updateParameter(fmod((rotationAngle+180), 360)/360);
    modTriangle.setZValue(99);
    QPolygonF modPolygon;
    modPolygon.append(QPointF(0, 0));
    modPolygon.append(QPointF(5, 15));
    modPolygon.append(QPointF(-5, 15));
    modPolygon.translate(width/2, 0);
    modTriangle.setPolygon(modPolygon);
    QPen modPen(Qt::NoPen);
    modTriangle.setPen(modPen);
    QColor modColor(YigColorKit::background2);
    modColor.setAlpha(200);
    QBrush modBrush(modColor);
    modTriangle.setBrush(modBrush);
    // Mod amount
    /*
    modElectron = new QGraphicsEllipseItem(0, 0, 25, 25, this);
    modElectron->moveBy(0, (boundingRect().width()/2) - 3);
    modElectron->setFlag( QGraphicsItem::ItemIsSelectable, false );
    modElectron->setFlag( QGraphicsItem::ItemIsMovable, false );
    modElectron->setCacheMode( QGraphicsItem::ItemCoordinateCache );
    QColor modColor(YigColorKit::background2);
    modColor.setAlpha(200);
    modElectron->setPen(QPen(modColor));
    modColor.setAlpha(20);
    modElectron->setBrush(modColor);*/

    /*
    QColor modFill(YigColorKit::background2);
    modFill.setAlpha(100);
    QColor modOutline(YigColorKit::background2);
    modOutline.setAlpha(220);
    modArc.setBrush(modFill);
    modArc.setPen(Qt::NoPen);*/
    //redrawArc();
}

YigModField::~YigModField()
{
    //delete modElectron;
}
/*
void YigModField::keyboardDelete()
{
    parentGraphic->keyboardDelete();
}
*/

void YigModField::updatePos(const QPointF &pos)
{

}

void YigModField::syncParam1(float value)
{
    setRotation(fmod((value * 360)+180, 360));
}

/*
void YigModField::itemClick(QGraphicsItem *item)
{

}*/

void YigModField::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    // Rotation happens here!
    /*
    qreal factor = -10;
    if(event->screenPos().y() < event->lastScreenPos().y())
    {
        factor *= -1;
    }

    rotationAngle += factor;

    if(rotationAngle < 0)
    {
        rotationAngle = 0;
    }

    else if(rotationAngle > 360)
    {
        rotationAngle = 359.9999;
    }*/

    rotationAngle = angleFromCenter(event->scenePos());
    setRotation(rotationAngle);
    transformOriginPoint();
    updateParameter(fmod((rotationAngle+180), 360)/360);
    QGraphicsEllipseItem::mouseMoveEvent(event);
    //redrawArc();
}

void YigModField::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //setCursor(Qt::SizeVerCursor);
    rotationAngle = angleFromCenter(event->scenePos());
    setRotation(fmod(rotationAngle, 360));
    transformOriginPoint();
    updateParameter(fmod((rotationAngle+180), 360)/360);
    QGraphicsEllipseItem::mousePressEvent(event);
}

void YigModField::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    //setCursor(Qt::ArrowCursor);
    rotationAngle = angleFromCenter(event->scenePos());
    setRotation(rotationAngle);
    transformOriginPoint();
    updateParameter(fmod((rotationAngle+180), 360)/360);
    QGraphicsEllipseItem::mouseReleaseEvent(event);
}
/*
QGraphicsEllipseItem* YigModField::getModElectron()
{
    return modElectron;
}
*/
YigSynthGraphic* YigModField::getParentGraphic()
{
    return parentGraphic;
}

int YigModField::type() const
{
    return YigBaseGraphic::ModFieldType;
}

void YigModField::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QStyleOptionGraphicsItem myOption = (*option);
    myOption.state &= !QStyle::State_Selected;
    QGraphicsEllipseItem::paint(painter, &myOption, widget);


    /*
    // Paint our highlight here
    if(option->state & QStyle::State_Selected)
    {
        QPen circlePen(YigBaseGraphic::highlightPen);
        circlePen.setWidth(2);
        painter->setPen(circlePen);
        painter->setBrush(Qt::NoBrush);
        //QColor circleBrush(painter->brush().color());
        //circleBrush.setAlpha(100);
        //painter->setBrush(circleBrush);
        painter->drawEllipse(boundingRect());
    }*/
    /*

    if(QString::compare(parentGraphic->selectingUser, USER_NAME) == 0)
    {
        painter->setPen(YigBaseGraphic::localUserHighlight);
        painter->setBrush(Qt::NoBrush);
        painter->drawEllipse(boundingRect());
    }

    else if(QString::compare(parentGraphic->selectingUser, " ") == 0)
    {

    }

    else
    {
        painter->setPen(YigBaseGraphic::otherUserHighlight);
        painter->setBrush(Qt::NoBrush);
        painter->drawEllipse(boundingRect());
    }*/
}

void YigModField::updateParameter(float parameter)
{
    parentGraphic->setParam1(parameter);
}

QVariant YigModField::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if(change == QGraphicsItem::ItemSelectedChange || change == QGraphicsItem::ItemSelectedHasChanged)
    {
        if(value.toBool()) parentGraphic->setSelected(true);
    }
    return QGraphicsEllipseItem::itemChange(change, value);
}

void YigModField::setSelected(bool selected)
{
    if(selected) parentGraphic->setSelected(true);
    QGraphicsEllipseItem::setSelected(selected);
}

qreal YigModField::angleFromCenter(QPointF point)
{
    qreal angle = fmod((atan2(point.y() - parentGraphic->sceneBoundingRect().center().y(),
                 point.x() - parentGraphic->sceneBoundingRect().center().x()) * 180 / PI)+ 90, 360);

    if(angle < 0)
    {
        angle += 360;
    }

    return angle;
}

void YigModField::redrawArc()
{
    qreal arcAngle;
    float arcWidth, arcHeight;

    arcAngle = rotationAngle;

    QPainterPath arcPath;

    arcPath.moveTo(boundingRect().center());
    /*
    //arcPath.moveTo((YigSynthGraphic::MOD_FIELD_SIZE/2) - (YigSynthGraphic::MOD_FIELD_2_SIZE/2), YigSynthGraphic::MOD_FIELD_SIZE/2);
    arcPath.cubicTo(boundingRect().center(), QPointF(0, 0), QPointF(0, boundingRect().height()/2));
    //QPointF endPoint(0, boundingRect().height()/2);
    */

    float size = rotationAngle/360;

    QRectF angleRect = QRectF((boundingRect().width()/2) - ((boundingRect().width()/2) * size),
                              (boundingRect().height()/2) - ((boundingRect().height()/2) * size),
                              boundingRect().width() * size,
                              boundingRect().height() * size);

    /*
    //arcPath.addEllipse(angleRect.center(), angleRect.width() * size /2, angleRect.height() * size /2);
    arcPath.cubicTo(angleRect.topLeft() * size,
                    angleRect.bottomRight() * size,
                    angleRect.bottomRight());
    arcPath.cubicTo(angleRect.topLeft() * size,
                    angleRect.bottomRight() * size,
                    angleRect.center());
    arcPath.setFillRule(Qt::OddEvenFill);*/

    arcPath.arcTo(boundingRect(), -180, rotationAngle);
    arcPath.cubicTo(boundingRect().bottomLeft(), boundingRect().topRight(), boundingRect().center());

    QPolygonF arcPolygon = arcPath.toFillPolygon();
    modArc.setPolygon(arcPolygon);
}

void YigModField::createModCircle()
{
    int modWidth = boundingRect().width() * 2/3;
    modElectron = new QGraphicsEllipseItem(0, 0, modWidth, modWidth, this);
    modElectron->moveBy((boundingRect().width() / 2) - (modWidth / 2), (boundingRect().height() / 2) - (boundingRect().height() / 2));
    modElectron->setFlag( QGraphicsItem::ItemIsSelectable, false );
    modElectron->setFlag( QGraphicsItem::ItemIsMovable, false );
    modElectron->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
    QColor modColor(YigColorKit::background2);
    modColor.setAlpha(165);
    QPen modPen(modColor);
    //modPen.setStyle(Qt::DotLine);
    modPen.setWidth(2);
    modElectron->setPen(modPen);
    modColor = YigColorKit::background2;
    modColor.setAlpha(20);
    modElectron->setBrush(modColor);
}


///////////////////////
// YigModField2
///////////////////////

YigModField2::YigModField2(YigSynthGraphic *synthGraphic, float param, qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent) :
    YigModField(synthGraphic, param, x, y, width, height, parent)
{
    //createModCircle();
    QColor modColor(YigColorKit::background2);
    //modColor.setAlpha(150);
    QBrush modBrush(modColor);
    modTriangle.setBrush(modBrush);
    modTriangle.setZValue(999);
}

int YigModField2::type() const
{
    return YigBaseGraphic::ModFieldType2;
}

void YigModField2::updateParameter(float parameter)
{
    parentGraphic->setParam2(parameter);
}

void YigModField2::syncParam2(float value)
{
    setRotation(fmod((value * 360)+180, 360));
}

void YigModField2::createModCircle()
{
    int modWidth = boundingRect().width() * 3/4;
    delete modElectron;
    modElectron = new QGraphicsEllipseItem(0, 0, modWidth, modWidth, this);
    modElectron->moveBy((boundingRect().width() / 2) - (modWidth / 2), (boundingRect().height() / 2) - (boundingRect().height() / 2));
    modElectron->setFlag( QGraphicsItem::ItemIsSelectable, false );
    modElectron->setFlag( QGraphicsItem::ItemIsMovable, false );
    modElectron->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
    QColor modColor(YigColorKit::background2);
    modColor.setAlpha(165);
    QPen modPen(modColor);
    //modPen.setStyle(Qt::DotLine);
    modPen.setWidth(2);
    modElectron->setPen(modPen);
    modColor = YigColorKit::background2;
    modColor.setAlpha(20);
    modElectron->setBrush(modColor);
}

///////////////////
// YigSignalArrow
//////////////////

YigSignalArrow::YigSignalArrow(YigSynthGraphic::EllipseType arrowType, YigSynthGraphic *parentGraphic) :
    QGraphicsEllipseItem(0, 0, ARROW_SIZE, ARROW_SIZE, parentGraphic),
    mArrowType(arrowType),
    mParentGraphic(parentGraphic),
    arrow(this)
{
    setFlag(QGraphicsItem::ItemIsSelectable, false);
    setFlag(QGraphicsItem::ItemIsMovable, false);
    setCacheMode(QGraphicsItem::DeviceCoordinateCache);

    /*
    QVector<QPointF> pointVector;
    pointVector.append(QPoint(0, 0));
    pointVector.append(QPoint(6, 13));
    pointVector.append(QPoint(0, 0));
    pointVector.append(QPoint(-7, 13));
    QPolygonF triangle(pointVector);
    setPolygon(triangle);
    */

    /*
    halfArrow = new QGraphicsLineItem(0, 0, 0, ARROW_SIZE/2, this);
    halfArrow->setFlag(QGraphicsItem::ItemIsSelectable, false);
    halfArrow->setFlag(QGraphicsItem::ItemIsMovable, false);
    halfArrow->setCacheMode(QGraphicsItem::ItemCoordinateCache);
    halfArrow->setRotation(30);
    */
    setupArrow();
}

YigSignalArrow::~YigSignalArrow()
{
    //delete halfArrow;
}

YigSynthGraphic::EllipseType YigSignalArrow::getArrowType()
{
    return mArrowType;
}

YigSynthGraphic* YigSignalArrow::getParentGraphic()
{
    return mParentGraphic;
}

int YigSignalArrow::type() const
{
    return YigBaseGraphic::SignalArrow;
}

void YigSignalArrow::setupArrow()
{
    QColor fillColor,outlineColor, arrowFill, arrowOutline;

    QPolygonF arrowPolygon;
    arrow.setZValue(1);
    switch(mArrowType)
    {

    case YigSynthGraphic::AUDIO_INPUT:
        /*
        arrowPolygon.append(QPointF(0, 0));
        arrowPolygon.append(QPointF(-5, 5));
        arrowPolygon.append(QPointF(0, 0));
        arrowPolygon.append(QPointF(5, 5));*/
        arrowPolygon.append(QPointF(2, ARROW_SIZE-4));
        arrowPolygon.append(QPointF(ARROW_SIZE-4, ARROW_SIZE-4));
        arrowPolygon.append(QPointF(ARROW_SIZE-4, 2));
        arrowPolygon.append(QPointF(ARROW_SIZE-6, ARROW_SIZE-6));
        arrow.setPolygon(arrowPolygon);

        moveBy(-3-YigSynthGraphic::ELLIPSE_SIZE/2,
                -(YigSynthGraphic::ELLIPSE_SIZE/2));
        fillColor = YigColorKit::background2;
        outlineColor = YigColorKit::background2;
        arrowFill = YigColorKit::focus1;
        arrowOutline = YigColorKit::focus1;
        break;

        /*
    case YigSynthGraphic::AUDIO_OUTPUT:
        moveBy((YigSynthGraphic::ELLIPSE_SIZE/2) - (boundingRect().width()/2) + (ARROW_SIZE/2),
               (YigSynthGraphic::ELLIPSE_SIZE/2) + (YigSynthGraphic::MOD_FIELD_SIZE/2) - (ARROW_SIZE/2));
        //setRotation(180);
        //transformOriginPoint();
        //fillColor = YigColorKit::focus1Highlight;
        fillColor = QColor(55,55,55);
        break;*/

    case YigSynthGraphic::MOD_INPUT:
        arrowPolygon.append(QPointF(4, 2));
        arrowPolygon.append(QPointF(4, ARROW_SIZE-4));
        arrowPolygon.append(QPointF(ARROW_SIZE-2, ARROW_SIZE-4));
        arrowPolygon.append(QPointF(6, ARROW_SIZE-6));
        arrow.setPolygon(arrowPolygon);
        moveBy(YigSynthGraphic::ELLIPSE_SIZE + (YigSynthGraphic::ELLIPSE_SIZE/2) - (ARROW_SIZE/2),
               -4-(YigSynthGraphic::ELLIPSE_SIZE/2)  + (ARROW_SIZE/2));
        fillColor = YigColorKit::accent;
        outlineColor = YigColorKit::background2;
        arrowFill = YigColorKit::background2;
        arrowOutline = YigColorKit::background2;

        break;
    }

    //setPen(fillColor);
    fillColor.setAlpha(220);
    setPen(Qt::NoPen);
    //setBrush(QBrush(fillColor));
    arrow.setBrush(fillColor);
    arrow.setPen(fillColor);
    arrow.transformOriginPoint();
    //halfArrow->setPen(fillColor);
}
